package files

import (
	"fmt"
	"io/fs"
	"os"
	"path"
	"path/filepath"
	"strings"

	"qingbing/xzutils/basic"
)

/*
 * 获取目录下的文件列表
 * dir: 扫描目录
 * ignores : 忽略文件或文件夹
 * recursion : 是否递归查找
 */
func FileList(dir string, ignores basic.KSlice, recursion bool) (res []string, err error) {
	dir = strings.TrimRight(dir, "/")
	fs, err := os.ReadDir(dir)
	if err != nil {
		return
	}
	m := ignores.ToMap()
	for _, f := range fs {
		fullName := path.Join(dir, f.Name())
		if _, ok := m[fullName]; ok { // 出现在过滤中
			continue
		}

		if f.IsDir() {
			if recursion {
				var subRes []string
				subRes, err = FileList(fullName, ignores, true)
				if err != nil {
					return
				}
				res = append(res, subRes...)
			}
			continue
		}
		res = append(res, fullName)
	}
	return
}

/*
 * 复制目录
 * src: 复制源目录
 * dist: 目标目录
 * ignores : 忽略文件或文件夹
 */
func CopyDir(src, dist string, ignores basic.KSlice) error {
	ds, err := fs.ReadDir(os.DirFS(src), ".")
	if err != nil {
		return err
	}
	// 确保目标目录存在
	if info, err := os.Stat(dist); err != nil || (info != nil && !info.IsDir()) {
		if err = os.Mkdir(dist, os.ModePerm); err != nil {
			return err
		}
	}
	m := ignores.ToMap()
	for _, file := range ds {
		filename := file.Name()
		if _, ok := m[filename]; ok { // 出现在过滤中
			continue
		}
		srcFile := path.Join(src, file.Name())
		distFile := path.Join(dist, file.Name())
		if file.IsDir() {
			if err = CopyDir(srcFile, distFile, ignores); err != nil {
				return err
			}
		} else if _, err = CopyFile(path.Join(src, file.Name()), path.Join(dist, file.Name())); err != nil {
			return err
		}
	}
	return nil
}

/*
 * 删除目录
 * dir: 操作目录
 * rmSelf: 是否删除指定当前路径目录
 */
func RmDir(dir string, rmSelf bool) error {
	// 路径转换成绝对路径
	dir, err := filepath.Abs(dir)
	if err != nil {
		return err
	}

	// 读取目录
	ds, err := fs.ReadDir(os.DirFS(dir), ".")
	if err != nil {
		return err
	}

	// 遍历目录
	for _, file := range ds {
		fmt.Printf("file: %s\n", file)
		path := path.Join(dir, file.Name())
		if file.IsDir() {
			err = RmDir(path, true)
		} else {
			// 删除文件
			err = os.Remove(path)
		}
		if err != nil {
			return err
		}
	}
	if rmSelf != true {
		return nil
	}
	return os.Remove(dir)
}

/*
 * 清空目录下所有文件和目录
 * dir: 操作目录
 */
func FlushDir(dir string) error {
	return RmDir(dir, false)
}
